home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
me_cd22.zip
/
DOC.ZIP
/
OBJECT.DOC
< prev
next >
Wrap
Text File
|
1992-04-27
|
8KB
|
266 lines
-*-text-*-
General decussion of OOP stuff. Add to insideMutt.
Don't do typedefs or structs, go directly to objects.
LISTS and SETS
----- --- ----
Definitions:
LIST: an ordered set of heterogeneous objects.
OSET: an ordered set of homogeneous objects.
Notes:
A string is an oset.
I think that an unordered set is easy to fake from an oset.
Lists and osets expand/contract as needed.
???The first element of a list or oset is numbered 1. This means the
0-th element is before the first element in a list. Handy for some
operations.
??? what is the empty set??? []
Set is a bad name: how about sequence, chain, list, pool, goo???
Rejected: vector, collection
LIST SYNTAX
Need an empty set: [], at least for notation.
Nothing special is needed but it might be nice to add some syntactic
sugar.
A oset constant: [1 2 3], the empty set is [].
Use: (nth-item ["one" "two" "three"] n) (same as switch)
(foo ["fee" "fie" "foe" "fum"]) (same as (foo (concat ...))
From CLisp: #(item item ...), #() is empty set. CL book suggests []
notation is better but users might want to use [] themselves.
LIST OPERATIONS
list/oset operations (foo and bar are lists or sets):
This is array like notation (always uses an index). Might be pretty
inefficient/awkward commparded to pointer syntax (ala lisp).
(list type list-name): Create a list.
All lists are set to the empty list at creation.
(list string foo): Create a list of lists.
(list list string foo): Create a list of lists containing strings.
Kinda like a 2d array.
#if 0 /* this is array syntax, not list syntax */
(foo n): returns the nth element of foo AS AN atom (if possible)
eg ("abc" 2) => 'b', ([1 2 3] 2) => 2,
([[1] [2 2] [3 3 3]] 2) => [2 2].
use (n-items). Use (cast-to) if need to atomify (atomize?).
(foo n object): Replaces the nth element of foo with object.
eg ("abc" 2 'z') => "azc", ([1 2 3] 2 123) => [1 123 3]
eg ("abc" 2 "xyz") => ???
use (replace-item)
#endif
(foo) returns the contents of foo.
(foo object [object ...])
Clears foo, concatanates all the objects and puts them in foo.
(foo []) Resets foo, ie foo contains the empty list.
(foo "testing" " 123") => (foo) == "testing 123".
(length-of foo): number of objects in foo.
(length-of []) => 0.
(n-items foo n [z]):
Trys to return a list of length z made by coping z elements of foo
starting at (and including) the nth.
z defaults to 1.
???(n-items foo 1) is the first element of foo.
If (z <= 0) or (n > (length-of foo)) or (foo == []), returns [].
If ask for more elements than can get, return as much as can.
(n-items "123" 2) => "2", (n-items "123" 2 2) => "23"
(n-items [] n z) => []
???If need an atom, use (cast-to ...)
(concat foo bar): returns a new list.
(concat [] []) => []
(concat foo []) => foo
(concat [] bar) => bar
(add-to foo n object [object ...]):
Insert object(s) into foo after the nth element.
If n >= (length foo), this op would be the same as (foo (concat foo
bar)) and would save some data copies. Maybe just use (add-at
foo (length foo) bar).
If (n < "first element"), prepend ie same as (foo (concat bar foo))
(add-to [] n bar) => ???error, can't save result or just stash in
RV ie same as (concat [] bar).
eg (add-to "123" 1 "9") => "1923"
(remove-items foo n [z]): Remove z items from foo starting at
(including) n. z defaults to 1. This could be implemented as
(foo (n-items foo 1 (- n 1)) (n-items foo (+ n 1) (length foo))).
If (n >= (length foo)) => foo
If try to remove more elements than in foo, return [].
If (z <= 0) return foo.
(remove-items [] n [z]): [].
(replace-items foo n z object [object ...])
Same as (remove-items foo n z)(add-to foo n-1 object [object ...])
Misc: These could be Mutt routines.
(is-in foo object [n [m]]) ?? (in-list)
Returns <something> if object is in list foo.
Return: TRUE/FALSE or n/-1
Start at n, end at m.
??? what about arb objects, how compare?
(apply-to foo Mutt-fcn): For every item in foo, call Mutt-fcn and
pass it the nth item of foo.
Problems:
Lists or osets of lists or osets.
How do I (joe mutt programmer) know what (nth-item foo-list n) is? Is
there a (type foo)? What happens when foo is a user defined object?
That would mean a central (MM) dictionary of tuples: (object type
#, object description). Many disjoint programs might share objects
so the compiler would have to generate code that registered an
object and stashed the type so it could be used for type checking,
etc. 1 byte is probably not enough for all the possible types.
This would be a pretty cool concept - ME could generate types for
buffer/bag/region stats, etc so I could do better type checking.
(msg) would work automagically with objects. On the other hand it
might a be a real drag to implement, slow things down and use up
lots more space. If I don't implement this, JP would have to know
(by putting a type field in the object) how to figure out the object
type. Maybe the best idea is just punt lists and stick with osets.
OBJECTS
-------
(object
DATA
{
}
CREATE ;; constructer
{
}
FREE ;; destructer
{
}
methods
overloading
...
}
A struct is just the data subset of this.
Object data is built on top of basic/atomic Mutt types: NUMBER (byte,
int, INT), STRING, ?VOID, REAL, BOOLEAN, BLOB, FCNPTR, LIST, array.
PROBLEMS
--------
How manage types that are:
- fixed length, fixed object size (NUMBER, REAL, BOOLEAN)
- fixed length, unknown object size (FCNPTR)
- unknown length, fixed object size (STRING)
- unknown length, unknown object size (LIST)
- objects that are built from the above types
How store, get and set.
What about:
- (loc object): How do I type check?
- How do I type check objects? do I need to?
EXAMPLES
--------
(object Buffer
DATA
{
(int buffer-id)
}
CREATE ;; constructer
{
(buffer-id (create-buffer))
}
FREE ;; destructer
{
(free-buffer buffer-id)
}
info
{
}
methods
overloading
...
}
(object Mark
DATA
{
(int mark-id)
}
CREATE ;; constructer
{
(mark-id (create-mark))
}
FREE ;; destructer
{
(free-mark mark-id)
}
methods
overloading
...
}
mark-rings
IMPLEMENTATIONS
---------------
Smalltalk Model
code varables object table objects
Var : contents index : pointer address : contents
list a : 3 1 : aaa
string b : 1 2 : xxx
3 : bbb
Each object varible in the code contains a 2 byte object number that is
an index into the object table. The object table contains pointers to
the actual objects.
Get: The address of object n is: object-table[n]
Set:
Allocate:
Look though object table until find an index that is unused.
If none: GC.
Repeat lookup.
If object table full (GC didn't free anything):
Expand object table.
If can't: fail.
Return index.
GC:
(1) Mark all entries in the object table as dead.
(2) For all live code object variables, mark object-table[var-index]
as live.
(3) Free all objects marked as dead in the object table.
Variation 1 on the Smalltalk model:
Move object table into the objects.
- Don't use a object table.
- Each object is linked to the next object.
- Vars contain pointers to the actual objects.
Pros:
- Less to think about and manage.
- Object look up is faster.
Cons:
- Probably uses more space.
Variation 2:
Copy objects instead of mark/sweep:
Look though object table
If object in use, copy it to a new list
Free all objects in the orginal list.
When garbage collect:
- When malloc fails
- When a program is done running
- When a block is freed